package py.com.alfa.escriba.web.services.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import py.com.alfa.escriba.exception.ErrorCode;
import py.com.alfa.escriba.exception.ServiceException;
import py.com.alfa.escriba.persistence.dao.AdminDAO;
import py.com.alfa.escriba.persistence.dao.ComparecientesDAO;
import py.com.alfa.escriba.persistence.dao.ControlesDAO;
import py.com.alfa.escriba.persistence.dao.ControlesEscriturasDAO;
import py.com.alfa.escriba.persistence.dao.ControlesFormulariosDAO;
import py.com.alfa.escriba.persistence.dao.ControlesNaturalezasDAO;
import py.com.alfa.escriba.persistence.dao.ControlesPersonasComparecientesDAO;
import py.com.alfa.escriba.persistence.dao.ControlesPersonasDAO;
import py.com.alfa.escriba.persistence.dao.ControlesVehiculosDAO;
import py.com.alfa.escriba.persistence.dao.ControlesinmueblesDAO;
import py.com.alfa.escriba.persistence.dao.ControlestextoDAO;
import py.com.alfa.escriba.persistence.dao.EscribanosDAO;
import py.com.alfa.escriba.persistence.dao.FormulariosDAO;
import py.com.alfa.escriba.persistence.dao.InmueblesDAO;
import py.com.alfa.escriba.persistence.dao.MonedasDAO;
import py.com.alfa.escriba.persistence.dao.NaturalezasDAO;
import py.com.alfa.escriba.persistence.dao.PaisDAO;
import py.com.alfa.escriba.persistence.dao.PersonasDAO;
import py.com.alfa.escriba.persistence.dao.PersonasjuridicasinfoDAO;
import py.com.alfa.escriba.persistence.dao.ReferenciaDAO;
import py.com.alfa.escriba.persistence.dao.VehiculosDAO;
import py.com.alfa.escriba.persistence.dto.ComparecientesDTO;
import py.com.alfa.escriba.persistence.dto.ControlesDTO;
import py.com.alfa.escriba.persistence.dto.ControlesEscriturasDTO;
import py.com.alfa.escriba.persistence.dto.ControlesFormulariosInfoDTO;
import py.com.alfa.escriba.persistence.dto.ControlesInfoDTO;
import py.com.alfa.escriba.persistence.dto.ControlesInmueblesInfoDTO;
import py.com.alfa.escriba.persistence.dto.ControlesNaturalezasDTO;
import py.com.alfa.escriba.persistence.dto.ControlesNaturalezasInfoDTO;
import py.com.alfa.escriba.persistence.dto.ControlesPersonasComparecientesDTO;
import py.com.alfa.escriba.persistence.dto.ControlesPersonasDTO;
import py.com.alfa.escriba.persistence.dto.ControlesPersonasInfoDTO;
import py.com.alfa.escriba.persistence.dto.ControlesVehiculosDTO;
import py.com.alfa.escriba.persistence.dto.ControlesVehiculosInfoDTO;
import py.com.alfa.escriba.persistence.dto.ControlesinmueblesDTO;
import py.com.alfa.escriba.persistence.dto.ControlestextoDTO;
import py.com.alfa.escriba.persistence.dto.EscribanosDTO;
import py.com.alfa.escriba.persistence.dto.InmueblesDTO;
import py.com.alfa.escriba.persistence.dto.MonedasDTO;
import py.com.alfa.escriba.persistence.dto.NaturalezasDTO;
import py.com.alfa.escriba.persistence.dto.PersonaInfoParaControlDTO;
import py.com.alfa.escriba.persistence.dto.PersonasjuridicasinfoDTO;
import py.com.alfa.escriba.persistence.dto.VehiculosDTO;
import py.com.alfa.escriba.persistence.dto.admin.PersonaDTO;
import py.com.alfa.escriba.persistence.dto.query.ControlesQueryDTO;
import py.com.alfa.escriba.persistence.dto.query.ControlesRequestDTO;
import py.com.alfa.escriba.persistence.dto.referencia.DistritoDTO;
import py.com.alfa.escriba.persistence.dto.referencia.TabRefDTO;
import py.com.alfa.escriba.util.Utils;
import py.com.alfa.escriba.web.interceptor.InvocationContext;
import py.com.alfa.escriba.web.services.ControlesService;

public class ControlesServiceImpl implements ControlesService{
	
	private Logger log = LoggerFactory.getLogger(getClass());

	private ControlesDAO controlesDAO;
	private AdminDAO adminDAO;
	private ControlesNaturalezasDAO controlesNaturalezasDAO;
	private ControlesPersonasDAO controlesPersonasDAO;
	private ControlesVehiculosDAO controlesVehiculosDAO;
	private ControlesFormulariosDAO controlesFormulariosDAO;
	private ControlesEscriturasDAO controlesEscriturasDAO;
	private FormulariosDAO formulariosDAO;
	private PersonasDAO personasDAO;
	private EscribanosDAO escribanosDAO;
	private NaturalezasDAO naturalezasDAO;
	private MonedasDAO monedasDAO;
	private PaisDAO paisDAO;
	private VehiculosDAO vehiculosDAO;
	private ControlesinmueblesDAO controlesInmueblesDAO;
	private InmueblesDAO inmueblesDAO;
	private ReferenciaDAO referenciaDAO;
	private ControlesPersonasComparecientesDAO controlesPersonasComparecientesDAO;
	private ComparecientesDAO comparecientesDAO;
	private PersonasjuridicasinfoDAO personasJuridicasInfoDAO;
	private ControlestextoDAO controlesTextoDAO;

	public void setControlesTextoDAO(ControlestextoDAO controlesTextoDAO) {
		this.controlesTextoDAO = controlesTextoDAO;
	}
	
	public void setControlesPersonasComparecientesDAO(
			ControlesPersonasComparecientesDAO controlesPersonasComparecientesDAO) {
		this.controlesPersonasComparecientesDAO = controlesPersonasComparecientesDAO;
	}

	public void setPersonasJuridicasInfoDAO(
			PersonasjuridicasinfoDAO personasJuridicasInfoDAO) {
		this.personasJuridicasInfoDAO = personasJuridicasInfoDAO;
	}

	public void setComparecientesDAO(ComparecientesDAO comparecientesDAO) {
		this.comparecientesDAO = comparecientesDAO;
	}

	public void setInmueblesDAO(InmueblesDAO inmueblesDAO) {
		this.inmueblesDAO = inmueblesDAO;
	}

	public void setControlesInmueblesDAO(ControlesinmueblesDAO controlesInmueblesDAO) {
		this.controlesInmueblesDAO = controlesInmueblesDAO;
	}

	public void setControlesEscriturasDAO(ControlesEscriturasDAO controlesEscriturasDAO) {
		this.controlesEscriturasDAO = controlesEscriturasDAO;
	}

	public void setControlesFormulariosDAO(ControlesFormulariosDAO controlesFormulariosDAO) {
		this.controlesFormulariosDAO = controlesFormulariosDAO;
	}

	public void setControlesDAO(ControlesDAO controlesDAO) {
		this.controlesDAO = controlesDAO;
	}

	public void setFormulariosDAO(FormulariosDAO formulariosDAO) {
		this.formulariosDAO = formulariosDAO;
	}

	public void setAdminDAO(AdminDAO adminDAO) {
		this.adminDAO = adminDAO;
	}
	public void setVehiculosDAO(VehiculosDAO vehiculosDAO) {
		this.vehiculosDAO = vehiculosDAO;
	}
	public void setControlesNaturalezasDAO(ControlesNaturalezasDAO controlesNaturalezasDAO) {
		this.controlesNaturalezasDAO = controlesNaturalezasDAO;
	}

	public void setControlesPersonasDAO(ControlesPersonasDAO controlesPersonasDAO) {
		this.controlesPersonasDAO = controlesPersonasDAO;
	}
	
	public void setControlesVehiculosDAO(ControlesVehiculosDAO controlesVehiculosDAO) {
		this.controlesVehiculosDAO = controlesVehiculosDAO;
	}

	public void setPersonasDAO(PersonasDAO personasDAO) {
		this.personasDAO = personasDAO;
	}

	public void setEscribanosDAO(EscribanosDAO escribanosDAO) {
		this.escribanosDAO = escribanosDAO;
	}

	public void setNaturalezasDAO(NaturalezasDAO naturalezasDAO) {
		this.naturalezasDAO = naturalezasDAO;
	}
	
	public void setMonedasDAO(MonedasDAO monedasDAO) {
		this.monedasDAO = monedasDAO;
	}

	public void setPaisDAO(PaisDAO paisDAO) {
		this.paisDAO = paisDAO;
	}
	
	public void setReferenciaDAO(ReferenciaDAO referenciaDAO) {
		this.referenciaDAO = referenciaDAO;
	}

	@Override
	public List<ControlesDTO> listControles(InvocationContext ic)
			throws ServiceException {
		List<ControlesDTO> controles= controlesDAO.listControles();
		return controles;
	}

	@Override
	public ControlesInfoDTO getControles(Long id, InvocationContext ic)
			throws ServiceException {
		if (id == null || id <= 0)
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","id");

		ControlesDTO c =  controlesDAO.getControlesById(id);
		
		if (c == null)
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"controles.not.exist", id);
		
		ControlesInfoDTO control = new ControlesInfoDTO();
		control.setId(c.getId());
		control.setNrocontrol(c.getNrocontrol());
		control.setIdescribano(c.getIdescribano());
		control.setFecha(c.getFecha());
		control.setNroorden(c.getNroorden());
		control.setDescripcion(c.getDescripcion());
		control.setReferencia(c.getReferencia());
		control.setConcepto(c.getConcepto());
		control.setObservacion(c.getObservacion());
		control.setIdestado(c.getIdestado());
		control.setIdusuario(c.getIdusuario());
		control.setFechacreacion(c.getFechacreacion());
		control.setIdusuariomodificacion(c.getIdusuariomodificacion());
		control.setFechamodificacion(c.getFechamodificacion());
		control.setTrn(c.getTrn());
		
		EscribanosDTO escribano= escribanosDAO.getEscribanosById(control.getIdescribano());
		PersonaDTO persona = personasDAO.obtenerPersona(escribano.getIdpersona());
		control.setEscribano(persona);
		TabRefDTO estado = adminDAO.getTabRefsById(control.getIdestado());
		control.setEstado(estado);
		List<ControlesPersonasInfoDTO> controlesPersonaInfo = new ArrayList<ControlesPersonasInfoDTO>();
		List<ControlesPersonasDTO> controlesPersonas = controlesPersonasDAO.getControlesPersonasByIdControl(control.getId());
		for(ControlesPersonasDTO cp:controlesPersonas){
			ControlesPersonasInfoDTO cpi= new ControlesPersonasInfoDTO();
			cpi.setId(cp.getId());
			cpi.setIdcontrol(cp.getIdcontrol());
			cpi.setIdpersona(cp.getIdpersona());
			log.info("cpi.idPersona:"+cpi.getIdpersona());
			cpi.setIdrol(cp.getIdrol());
			cpi.setIdpais(cp.getIdpais());
			cpi.setIdtipodocumento(cp.getIdtipodocumento());
			cpi.setNrodocumento(cp.getNrodocumento());
			cpi.setDvdocumento(cp.getDvdocumento());
			cpi.setIddomicilio(cp.getIddomicilio());
			cpi.setOrden(cp.getOrden());
			cpi.setCalidad(cp.getCalidad());
			cpi.setCalleprincipal(cp.getCalleprincipal());
			cpi.setCalidad(cp.getCalidad());
			cpi.setNumero(cp.getNumero());
			cpi.setPiso(cp.getPiso());
			cpi.setUnidad(cp.getUnidad());
			cpi.setIddepartamento(cp.getIddepartamento());
			cpi.setIddistrito(cp.getIddistrito());
			
			cpi.setPais(paisDAO.paisById(cp.getIdpais()));
			PersonaInfoParaControlDTO personaInfo=new PersonaInfoParaControlDTO();
			PersonaDTO per=personasDAO.obtenerPersona(cp.getIdpersona());
			if(per!=null){
				personaInfo.setNombreCompleto(per.getNombreCompleto());
				personaInfo.setId(per.getId());
				PersonasjuridicasinfoDTO perJur=personasJuridicasInfoDAO.getPersonaJuridicaByIdPersona(per.getId());
				if(perJur!=null){
					List<ControlesPersonasComparecientesDTO> controlesPersonasComp
					   = controlesPersonasComparecientesDAO.getControlesPersonasComparecientesByIdControlPersona(cp.getId());
					if(controlesPersonasComp!=null){
						List<ComparecientesDTO> comparecientes = comparecientesDAO.getComparecientesByIdPerJuridica(perJur.getId());
						if(comparecientes!=null){
							for(ComparecientesDTO comp: comparecientes ){
								comp.setRol(this.referenciaDAO.getTabRefById(comp.getIdRol()));
								comp.setEstadoCivilDTO(this.referenciaDAO.getTabRefById(comp.getIdEstadoCivil()));
								comp.setTipoDocumento(this.referenciaDAO.getTabRefById(comp.getIdTipoDocumento()));
								for(ControlesPersonasComparecientesDTO cpc: controlesPersonasComp){
									if(comp.getNombreCompleto().equals(cpc.getNombreCompleto()) &&
											comp.getNroDocumento().equals(cpc.getNroDocumento()) &&
											comp.getIdRol().equals(cpc.getIdRol())){
										comp.setMarcarControl(true);
										break;
									}
								}
							}
							personaInfo.setComparecientes(comparecientes);
						}
					}
				}
				
			}
			cpi.setPersona(personaInfo);
			//cpi.setPersona(personasDAO.obtenerPersona(cp.getIdpersona()));
			cpi.setTipoDocumento(adminDAO.getTabRefsById(cp.getIdtipodocumento()));
			cpi.setDomicilio(adminDAO.getDomicilio(cp.getIddomicilio()));
			cpi.setRol(adminDAO.getTabRefsById(cp.getIdrol()));
			cpi.setTipoDocumento(adminDAO.getTabRefsById(cp.getIdtipodocumento()));
			cpi.setControl(c);
			controlesPersonaInfo.add(cpi);
		}
		List<ControlesNaturalezasInfoDTO> controlesNaturalezaInfo = new ArrayList<ControlesNaturalezasInfoDTO>();
		List<ControlesNaturalezasDTO> controlesNaturaleza = controlesNaturalezasDAO.getControlesNaturalezasByIdControl(control.getId());
		for(ControlesNaturalezasDTO cn:controlesNaturaleza){
			ControlesNaturalezasInfoDTO cni= new ControlesNaturalezasInfoDTO();
			cni.setId(cn.getId());
			cni.setIdcontrol(cn.getIdcontrol());
			cni.setIdnaturaleza(cn.getIdnaturaleza());
			cni.setIdmoneda(cn.getIdmoneda());
			cni.setValor(cn.getValor());
			cni.setValorimponible(cn.getValorimponible());
			cni.setOrden(cn.getOrden());
			
			cni.setControl(c);
			MonedasDTO moneda = monedasDAO.getMonedasById(cn.getIdmoneda());
			cni.setMoneda(moneda);
			NaturalezasDTO naturaleza = naturalezasDAO.getNaturalezasById(cn.getIdnaturaleza());
			cni.setNaturaleza(naturaleza);
			controlesNaturalezaInfo.add(cni);
		}
		List<ControlesVehiculosInfoDTO> controlesVehiculosInfo= new ArrayList<ControlesVehiculosInfoDTO>();
		List<ControlesVehiculosDTO> controlesVehiculos= controlesVehiculosDAO.getControlesVehiculosByIdControl(control.getId());
		for(ControlesVehiculosDTO cv:controlesVehiculos){
			ControlesVehiculosInfoDTO cvi = new ControlesVehiculosInfoDTO();
			cvi.setId(cv.getId());
			cvi.setIdcontrol(cv.getIdcontrol());
			cvi.setIdvehiculo(cv.getIdvehiculo());
			cvi.setIdmoneda(cv.getIdmoneda());
			cvi.setValor(cv.getValor());
			cvi.setNrochasis(cv.getNrochasis());
			cvi.setOrden(cv.getOrden());
			cvi.setControl(c);
			VehiculosDTO vehiculo = vehiculosDAO.getVehiculosById(cv.getIdvehiculo());
			cvi.setVehiculo(vehiculo);
			MonedasDTO moneda = monedasDAO.getMonedasById(cv.getIdmoneda());
			cvi.setMoneda(moneda);
			controlesVehiculosInfo.add(cvi);
		}
		
		List<ControlesInmueblesInfoDTO> controlesInmueblesInfo= new ArrayList<ControlesInmueblesInfoDTO>();
		List<ControlesinmueblesDTO> controlesInmuebles = controlesInmueblesDAO.getControlesinmueblesByIdControl(control.getId());
		if(controlesInmuebles!=null){
			for(ControlesinmueblesDTO ci:controlesInmuebles){
				ControlesInmueblesInfoDTO cii= new ControlesInmueblesInfoDTO();
				cii.setId(ci.getId());
				cii.setIdcontrol(ci.getIdcontrol());
				cii.setIdinmueble(ci.getIdinmueble());
				cii.setIdmoneda(ci.getIdmoneda());
				cii.setFinca(ci.getFinca());
				cii.setMatricula(ci.getMatricula());
				cii.setValor(ci.getValor());
				cii.setOrden(ci.getOrden());

				cii.setControl(c);
				InmueblesDTO inmueble=inmueblesDAO.getInmueblesById(ci.getIdinmueble());
				DistritoDTO distrito = referenciaDAO.getDistritoById(inmueble.getIddistrito());
				inmueble.setDistrito(distrito);
				cii.setInmueble(inmueble);
				MonedasDTO moneda = monedasDAO.getMonedasById(ci.getIdmoneda());
				cii.setMoneda(moneda);
				controlesInmueblesInfo.add(cii);
			}
		}
		
		control.setNaturalezas(controlesNaturalezaInfo);
		control.setPersonas(controlesPersonaInfo);
		control.setVehiculos(controlesVehiculosInfo);
		control.setInmuebles(controlesInmueblesInfo);
		return control;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=ServiceException.class)
	public void deleteControles(Long id, InvocationContext ic)
			throws ServiceException {
		if (id == null || id <= 0)
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","id");

		ControlesDTO control =  controlesDAO.getControlesById(id);

		if(control == null)
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"controles.not.exist", id);

		try {

			List<ControlesPersonasDTO> controlesPersonas = controlesPersonasDAO.getControlesPersonasByIdControl(control.getId());
			for(ControlesPersonasDTO cp:controlesPersonas){
				controlesPersonasComparecientesDAO.deleteControlesPersonasComparecientesByIdControlPersona(cp.getId());
				controlesPersonasDAO.deleteControlesPersonas(cp);
			}
			List<ControlesNaturalezasDTO> controlesNaturaleza = controlesNaturalezasDAO.getControlesNaturalezasByIdControl(control.getId());
			for(ControlesNaturalezasDTO cn:controlesNaturaleza){
				controlesNaturalezasDAO.deleteControlesNaturalezas(cn);
			}
			List<ControlesVehiculosDTO> controlesVehiculos = controlesVehiculosDAO.getControlesVehiculosByIdControl(control.getId());
			if(controlesVehiculos!=null){
				for(ControlesVehiculosDTO cv:controlesVehiculos){
					controlesVehiculosDAO.deleteControlesVehiculos(cv);
				}
			}
			List<ControlesinmueblesDTO> controlesInmuebles = controlesInmueblesDAO.getControlesinmueblesByIdControl(control.getId());
			if(controlesInmuebles!=null){
				for(ControlesinmueblesDTO ci:controlesInmuebles){
					controlesInmueblesDAO.deleteControlesinmuebles(ci);
				}
			}
			
			controlesDAO.deleteControles(control);
		}
		catch (DataIntegrityViolationException e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.DATA_INTEGRITY_VIOLATION, "controles.constraint.violation", id);
		}

	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=ServiceException.class)
	public ControlesInfoDTO updateControles(Long id, ControlesInfoDTO dto,
			InvocationContext ic) throws ServiceException {
		
		if (id == null || id <= 0)
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","id");

		if (null == dto)
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","dto");

		ControlesDTO c =  controlesDAO.getControlesById(id);

		if (c == null)
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"controles.not.exist", id);	

		Utils.validarDTO(dto);
//		Integer ordenNat=1;
//		Integer ordenPer=1;
//		Integer ordenVehi=1;
		
		try{

			if(dto.getEliminar()!=null){
				if (dto.getEliminar().getNaturalezas() != null){
					for(ControlesNaturalezasInfoDTO cni : dto.getEliminar().getNaturalezas()){
						cni.setIdcontrol(dto.getId());
						controlesNaturalezasDAO.deleteControlesNaturalezas(cni);
					}
				}
				if (dto.getEliminar().getPersonas() != null){
					for(ControlesPersonasInfoDTO cpi: dto.getEliminar().getPersonas()){
						cpi.setIdcontrol(dto.getId());
						controlesPersonasComparecientesDAO.deleteControlesPersonasComparecientesByIdControlPersona(cpi.getId());
						controlesPersonasDAO.deleteControlesPersonas(cpi);
					}
				}
				if (dto.getEliminar().getVehiculos() != null){
					log.info("dto.getEliminar().getVehiculos().size()"+dto.getEliminar().getVehiculos().size());
					for(ControlesVehiculosInfoDTO cvi: dto.getEliminar().getVehiculos()){
						cvi.setIdcontrol(dto.getId());
						controlesVehiculosDAO.deleteControlesVehiculos(cvi);
					}
				}
				if (dto.getEliminar().getInmuebles()!= null){
					log.info("dto.getEliminar().getInmuebles().size()"+dto.getEliminar().getInmuebles().size());
					for(ControlesInmueblesInfoDTO cii: dto.getEliminar().getInmuebles()){
						cii.setIdcontrol(dto.getId());
						controlesInmueblesDAO.deleteControlesinmuebles(cii);
					}
				}
			}
			if(dto.getModificar()!=null){
				if (dto.getModificar().getNaturalezas() != null){
					for(ControlesNaturalezasInfoDTO cni : dto.getModificar().getNaturalezas()){
//						cni.setOrden(ordenNat);
//						ordenNat++;
						cni.setIdcontrol(dto.getId());
						controlesNaturalezasDAO.updateControlesNaturalezas(cni);
					}
				}
				if (dto.getModificar().getPersonas() != null){
					for(ControlesPersonasInfoDTO cpi: dto.getModificar().getPersonas()){
//						cpi.setOrden(ordenPer);
//						ordenPer++;
						cpi.setIdcontrol(dto.getId());
						controlesPersonasDAO.updateControlesPersonas(cpi);
						controlesPersonasComparecientesDAO.deleteControlesPersonasComparecientesByIdControlPersona(cpi.getId());
						if(cpi.getPersona().getComparecientes()!=null){
							log.info("cpi.getPersona().getComparecientes()!=null");
							for(ComparecientesDTO compar: cpi.getPersona().getComparecientes()){
								log.info("nombre:"+compar.getNombreCompleto()+" marcarControl:"+compar.getMarcarControl());
								if(compar.getMarcarControl()){
									ControlesPersonasComparecientesDTO cpc= new ControlesPersonasComparecientesDTO();
									cpc.setIdControlesPersona(cpi.getId());
									cpc.setIdEstadoCivil(compar.getIdEstadoCivil());
									cpc.setIdPais(compar.getIdPais());
									cpc.setIdPoder(compar.getIdPoder());
									cpc.setIdRol(compar.getIdRol());
									cpc.setIdTipoDocumento(compar.getIdTipoDocumento());
									cpc.setNombreCompleto(compar.getNombreCompleto());
									cpc.setNroDocumento(compar.getNroDocumento());
									cpc.setFechacreacion(new Date(System.currentTimeMillis()));
									cpc.setIdUsuario(ic.getIdUserPrincipal());
									controlesPersonasComparecientesDAO.createControlesPersonasComparecientes(cpc);
								}
							}
						}

					}
				}
				if (dto.getModificar().getVehiculos() != null){
					log.info("dto.getModificar().getVehiculos().size()"+dto.getModificar().getVehiculos().size());
					for(ControlesVehiculosInfoDTO cvi: dto.getModificar().getVehiculos()){
//						cvi.setOrden(ordenVehi);
//						ordenVehi++;
						cvi.setIdcontrol(dto.getId());
						controlesVehiculosDAO.updateControlesVehiculos(cvi);
					}
				}
				if (dto.getModificar().getInmuebles() != null){
					log.info("dto.getModificar().getInmuebles().size()"+dto.getModificar().getInmuebles().size());
					for(ControlesInmueblesInfoDTO cii: dto.getModificar().getInmuebles()){
						cii.setIdcontrol(dto.getId());
						controlesInmueblesDAO.updateControlesinmuebles(cii);
					}
				}
								
			}
			if(dto.getAgregar()!=null){
				if (dto.getAgregar().getNaturalezas() != null){
					for(ControlesNaturalezasInfoDTO cni : dto.getAgregar().getNaturalezas()){
//						cni.setOrden(ordenNat);
//						ordenNat++;
						cni.setIdcontrol(dto.getId());
						controlesNaturalezasDAO.createControlesNaturalezas(cni);
					}
				}
				if (dto.getAgregar().getPersonas() != null){
					for(ControlesPersonasInfoDTO cpi: dto.getAgregar().getPersonas()){
//						cpi.setOrden(ordenPer);
//						ordenPer++;
						cpi.setIdcontrol(dto.getId());
						controlesPersonasDAO.createControlesPersonas(cpi);
						log.info("cpi.getPersona().getComparecientes():"+cpi.getPersona().getComparecientes());
						if(cpi.getPersona().getComparecientes()!=null){
							log.info("cpi.getPersona().getComparecientes()!=null");
							for(ComparecientesDTO compar: cpi.getPersona().getComparecientes()){
								log.info("nombre:"+compar.getNombreCompleto()+" marcarControl:"+compar.getMarcarControl());
								if(compar.getMarcarControl()){
									ControlesPersonasComparecientesDTO cpc= new ControlesPersonasComparecientesDTO();
									cpc.setIdControlesPersona(cpi.getId());
									cpc.setIdEstadoCivil(compar.getIdEstadoCivil());
									cpc.setIdPais(compar.getIdPais());
									cpc.setIdPoder(compar.getIdPoder());
									cpc.setIdRol(compar.getIdRol());
									cpc.setIdTipoDocumento(compar.getIdTipoDocumento());
									cpc.setNombreCompleto(compar.getNombreCompleto());
									cpc.setNroDocumento(compar.getNroDocumento());
									cpc.setFechacreacion(new Date(System.currentTimeMillis()));
									cpc.setIdUsuario(ic.getIdUserPrincipal());
									controlesPersonasComparecientesDAO.createControlesPersonasComparecientes(cpc);
								}
							}
							
						}
					}
				}
				if (dto.getAgregar().getVehiculos() != null){
					log.info("dto.getAgregar().getVehiculos().size()"+dto.getAgregar().getVehiculos().size());
					for(ControlesVehiculosInfoDTO cvi: dto.getAgregar().getVehiculos()){
//						cvi.setOrden(ordenVehi);
//						ordenVehi++;
						cvi.setIdcontrol(dto.getId());
						if(cvi.getIdvehiculo()==null){
							throw new ServiceException(ErrorCode.CODE_NOT_EXIST, "controles.not.vehiculo");
						}
						controlesVehiculosDAO.createControlesVehiculos(cvi);
					}
				}
				if (dto.getAgregar().getInmuebles() != null){
					log.info("dto.getAgregar().getInmuebles().size()"+dto.getAgregar().getInmuebles().size());
					for(ControlesInmueblesInfoDTO cii: dto.getAgregar().getInmuebles()){
						cii.setIdcontrol(dto.getId());
						if(cii.getIdinmueble()==null){
							throw new ServiceException(ErrorCode.CODE_NOT_EXIST, "controles.not.inmueble");
						}
						controlesInmueblesDAO.createControlesinmuebles(cii);
					}
				}
			}
			log.info("dto.getIdescribano():      ............."+dto.getIdescribano());
			dto.setTrn(controlesDAO.getTrnControles()+1L);
			dto.setFechamodificacion(new Date(System.currentTimeMillis()));
			dto.setIdusuariomodificacion(ic.getIdUserPrincipal());
			controlesDAO.updateControles(dto);
		}
		catch (DataIntegrityViolationException e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.DATA_INTEGRITY_VIOLATION, "controles.constraint.violation");
		}
		dto= this.getControles(dto.getId(), ic);
//		Utils.validarControl(dto);
		return dto;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=ServiceException.class)
	public ControlesInfoDTO createControles(ControlesInfoDTO dto,
			InvocationContext ic) throws ServiceException {
		if (dto == null)
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","dto");

		try {

			Utils.validarDTO(dto);
			Utils.validarControl(dto);
			Integer ordenNat=1;
			Integer ordenPer=1;
			Integer ordenVehi=1;
			Integer ordenInmu=1;
			
			Long trn = controlesDAO.getTrnControles();
		    dto.setTrn(trn+1L);
			
			if(ic.getIdEscribano() != null)
				dto.setIdescribano(ic.getIdEscribano());
			
			dto.setFecha(new Date(System.currentTimeMillis()));
			dto.setFechacreacion(new Date(System.currentTimeMillis()));
			dto.setIdusuario(ic.getIdUserPrincipal());
			controlesDAO.createControles(dto);
			if(dto.getId()==null){
				throw new ServiceException(ErrorCode.PARAMETER_ERROR,"controles.error.null");
			}
			for(ControlesNaturalezasInfoDTO cni : dto.getNaturalezas()){
				cni.setIdcontrol(dto.getId());
				cni.setOrden(ordenNat);
				ordenNat++;
				controlesNaturalezasDAO.createControlesNaturalezas(cni);
			}
			for(ControlesPersonasInfoDTO cpi: dto.getPersonas()){
				cpi.setIdcontrol(dto.getId());
				cpi.setOrden(ordenPer);
				ordenPer++;
				controlesPersonasDAO.createControlesPersonas(cpi);
				log.info("CREATE cpi.getPersona().getComparecientes():"+cpi.getPersona().getComparecientes());
				if(cpi.getPersona().getComparecientes()!=null){
					log.info("cpi.getPersona().getComparecientes()!=null");
					for(ComparecientesDTO compar: cpi.getPersona().getComparecientes()){
						log.info("nombre:"+compar.getNombreCompleto()+" marcarControl:"+compar.getMarcarControl());
						if(compar.getMarcarControl()){
							ControlesPersonasComparecientesDTO cpc= new ControlesPersonasComparecientesDTO();
							cpc.setIdControlesPersona(cpi.getId());
							cpc.setIdEstadoCivil(compar.getIdEstadoCivil());
							cpc.setIdPais(compar.getIdPais());
							cpc.setIdPoder(compar.getIdPoder());
							cpc.setIdRol(compar.getIdRol());
							cpc.setIdTipoDocumento(compar.getIdTipoDocumento());
							cpc.setNombreCompleto(compar.getNombreCompleto());
							cpc.setNroDocumento(compar.getNroDocumento());
							cpc.setFechacreacion(new Date(System.currentTimeMillis()));
							cpc.setIdUsuario(ic.getIdUserPrincipal());
							controlesPersonasComparecientesDAO.createControlesPersonasComparecientes(cpc);
						}
					}
					
				}
			}
			if ( dto.getVehiculos() != null){
				for(ControlesVehiculosInfoDTO cvi: dto.getVehiculos()){
					cvi.setIdcontrol(dto.getId());
					if(cvi.getIdvehiculo()==null){
						throw new ServiceException(ErrorCode.CODE_NOT_EXIST, "controles.not.vehiculo");
					}
					cvi.setOrden(ordenVehi);
					ordenVehi++;
					controlesVehiculosDAO.createControlesVehiculos(cvi);
				}
			}
			if(dto.getInmuebles() !=null){
				for(ControlesInmueblesInfoDTO cii: dto.getInmuebles()){
					cii.setIdcontrol(dto.getId());
					if(cii.getIdinmueble()==null){
						throw new ServiceException(ErrorCode.CODE_NOT_EXIST, "controles.not.inmueble");
					}
					cii.setOrden(ordenInmu);
					ordenInmu++;
					controlesInmueblesDAO.createControlesinmuebles(cii);
				}
			}
		}
		catch (DuplicateKeyException e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.DUPLICATE_KEY_EXCEPTION, "controles.duplicate.key");
		}
		return dto;
	}

	@Override
	public List<ControlesRequestDTO> listRequestControles(ControlesQueryDTO dto,InvocationContext ic) 	throws ServiceException {
		log.info("controlesQUERYDTO:"+dto);
		if(dto.getNombreCompleto()!=null){
			dto.setNombreCompleto("%"+dto.getNombreCompleto()+"%");
		}
		if(dto.getChasisSerie()!=null){
			dto.setChasisSerie("%"+dto.getChasisSerie()+"%");
		}
		List<ControlesRequestDTO> controles= controlesDAO.listRequestControles(dto);
		if (controles == null || controles.size() == 0)
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"controles.notfound");
		return controles;
	}

	@Override
	public ControlesFormulariosInfoDTO getControlesFormulariosById(Long id, InvocationContext ic) throws ServiceException {
		ControlesFormulariosInfoDTO controlesFormularios= controlesFormulariosDAO.getControlesFormulariosById(id);
		if (controlesFormularios == null )
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"controles.formularios.not.found");
		controlesFormularios.setFormulario(formulariosDAO.getFormulariosById(controlesFormularios.getIdFormulario()));
		if(controlesFormularios.getIdControlPersona()!=null)
			controlesFormularios.setControlPersona(controlesPersonasDAO.getControlesPersonasById(controlesFormularios.getIdControlPersona()));
		if(controlesFormularios.getIdControlVehiculo()!=null)
			controlesFormularios.setControlVehiculo(controlesVehiculosDAO.getControlesVehiculosById(controlesFormularios.getIdControlVehiculo()));
		
		return controlesFormularios;
	}

	@Override
	public List<ControlesFormulariosInfoDTO> getControlesFormulariosByIdControl(Long idControl, InvocationContext ic) throws ServiceException {
		List<ControlesFormulariosInfoDTO> controlesFormularios = controlesFormulariosDAO.getControlesFormulariosByIdControl(idControl);
		if (controlesFormularios != null && controlesFormularios.size() > 0){
			for (Iterator<ControlesFormulariosInfoDTO> it = controlesFormularios.iterator(); it.hasNext();) {
				ControlesFormulariosInfoDTO cfi = (ControlesFormulariosInfoDTO) it.next();
				cfi.setFormulario(formulariosDAO.getFormulariosById(cfi.getIdFormulario()));
				if(cfi.getIdControlPersona()!=null)
					cfi.setControlPersona(controlesPersonasDAO.getControlesPersonasById(cfi.getIdControlPersona()));
				if(cfi.getIdControlVehiculo()!=null)
					cfi.setControlVehiculo(controlesVehiculosDAO.getControlesVehiculosById(cfi.getIdControlVehiculo()));
			}
		}else{
			controlesFormularios = new ArrayList<ControlesFormulariosInfoDTO>();
		}
		
		return controlesFormularios;
	}

	@Override
	public ControlesInfoDTO updateControlesFormularios(Long id,
			ControlesInfoDTO dto, InvocationContext ic) throws ServiceException {
		if (id == null || id <= 0)
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","id");

		if (null == dto)
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","dto");

		ControlesDTO c =  controlesDAO.getControlesById(id);

		if (c == null)
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"controles.not.exist", id);	

		Utils.validarDTO(dto);
//		JSONTranslator<ControlesInfoDTO> jtrans = new JSONTranslator<ControlesInfoDTO>(ControlesInfoDTO.class);
//		log.info("CONTROL: {}", jtrans.toJSON(dto));
		
		try{

			if(dto.getEliminar()!=null){
				if (dto.getEliminar().getFormularios() != null){
					for(ControlesFormulariosInfoDTO cfi : dto.getEliminar().getFormularios()){
						cfi.setIdcontrol(dto.getId());
						controlesFormulariosDAO.deleteControlesFormularios(cfi);
					}
				}
			}
			if(dto.getModificar()!=null){
				if (dto.getModificar().getFormularios() != null){
					for(ControlesFormulariosInfoDTO cfi : dto.getModificar().getFormularios()){
						cfi.setIdcontrol(dto.getId());
						controlesFormulariosDAO.updateControlesFormularios(cfi);
					}
				}								
			}
			if(dto.getAgregar()!=null){
				if (dto.getAgregar().getFormularios() != null){
					for(ControlesFormulariosInfoDTO cfi : dto.getAgregar().getFormularios()){
						cfi.setIdcontrol(dto.getId());
						if(cfi.getFechaEmision()!=null){
							cfi.setFechaVencimiento(Utils.calcularVencimiento(cfi.getFechaEmision(), 30));
						}
						controlesFormulariosDAO.createControlesFormularios(cfi);
					}
				}
				
			}
//			log.info("dto.getIdescribano():      ............."+dto.getIdescribano());
			c.setFechamodificacion(new Date(System.currentTimeMillis()));
			c.setIdusuariomodificacion(ic.getIdUserPrincipal());
			controlesDAO.updateControles(c);
		}
		catch (DataIntegrityViolationException e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.DATA_INTEGRITY_VIOLATION, "controles.constraint.violation");
		}
		dto= this.getControles(dto.getId(), ic);
		Utils.validarControl(dto);
		return dto;
	}

	@Override
	public List<ControlesEscriturasDTO> listControlesEscrituraByIdControl(Long idControl, InvocationContext ic) throws ServiceException {
		log.info("idControl:"+idControl);
		List<ControlesEscriturasDTO> controlesEscrituras = controlesEscriturasDAO.getControlesEscriturasByIdControl(idControl);
		if (controlesEscrituras != null && controlesEscrituras.size() > 0){
			for (Iterator<ControlesEscriturasDTO> it = controlesEscrituras.iterator(); it.hasNext();) {
				ControlesEscriturasDTO ce = (ControlesEscriturasDTO) it.next();
				if(ce.getIdProtocolo()!=null){
					ce.setProtocolo(adminDAO.getTabRefsById(ce.getIdProtocolo()));
				}
				if(ce.getIdEstadoEscritura()!=null){
					ce.setEstado(adminDAO.getTabRefsById(ce.getIdEstadoEscritura()));
				}
			}
		}else{
			controlesEscrituras = new ArrayList<ControlesEscriturasDTO>();
		}
		
		return controlesEscrituras;
	}

	@Override
	public ControlesEscriturasDTO getControlesEscritura(Long id,InvocationContext ic) throws ServiceException {
		ControlesEscriturasDTO controlesEscrituras= controlesEscriturasDAO.getControlesEscriturasById(id);
		if (controlesEscrituras == null )
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"controles.escritura.not.found");
		return controlesEscrituras;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=ServiceException.class)
	public ControlesInfoDTO updateControlesEscritura(Long idControl,
			ControlesInfoDTO dto, InvocationContext ic) throws ServiceException {
		log.info("entro al updateControlesEscritura:"+idControl);
		log.info("dto:"+dto);
		if (idControl == null || idControl <= 0)
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","id");

		if (null == dto)
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","dto");

		ControlesDTO c =  controlesDAO.getControlesById(idControl);

		if (c == null)
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"controles.not.exist", idControl);	

		Utils.validarDTO(dto);

		try{

			if(dto.getEliminar()!=null){
				if (dto.getEliminar().getEscrituras() != null){
					for(ControlesEscriturasDTO cei : dto.getEliminar().getEscrituras()){
						controlesEscriturasDAO.deleteControlesEscrituras(cei);
					}
				}
			}
			if(dto.getModificar()!=null){
				if (dto.getModificar().getEscrituras() != null){
					for(ControlesEscriturasDTO cei : dto.getModificar().getEscrituras()){
						cei.setIdControl(dto.getId());
						cei.setIdEscribano(dto.getIdescribano());
						controlesEscriturasDAO.updateControlesEscrituras(cei);
					}
				}								
			}
			if(dto.getAgregar()!=null){
				if (dto.getAgregar().getEscrituras() != null){
					for(ControlesEscriturasDTO cei : dto.getAgregar().getEscrituras()){
						cei.setIdControl(dto.getId());
						cei.setIdEscribano(dto.getIdescribano());
						log.info("control Escritura a Crear:"+cei);
						controlesEscriturasDAO.createControlesEscrituras(cei);
					}
				}
				
			}
//			log.info("dto.getIdescribano():      ............."+dto.getIdescribano());
			c.setFechamodificacion(new Date(System.currentTimeMillis()));
			c.setIdusuariomodificacion(ic.getIdUserPrincipal());
			c.setIdestado(dto.getIdestado());
			controlesDAO.updateControles(c);
		}
		catch (DataIntegrityViolationException e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.DATA_INTEGRITY_VIOLATION, "controles.constraint.violation");
		}
		dto= this.getControles(dto.getId(), ic);
		Utils.validarControl(dto);
		return dto;
	}

	@Override
	public ControlestextoDTO getControlesTextoByIdControl(Long idControl,
			InvocationContext ic) throws ServiceException {
		log.info("idControl:"+idControl);
		ControlestextoDTO controlestexto = controlesTextoDAO.getControlestextoByIdControl(idControl);

		return controlestexto;
	}

	@Override
	public ControlestextoDTO getControlesTexto(Long id, InvocationContext ic)
			throws ServiceException {
		log.info("id:"+id);
		ControlestextoDTO controlestexto = controlesTextoDAO.getControlestextoById(id);

		return controlestexto;
	}

	@Override
	public ControlesInfoDTO updateControlesTexto(Long idControl,
			ControlesInfoDTO dto, InvocationContext ic) throws ServiceException {
		log.info("entro al updateControlesTexto:"+idControl);
		log.info("dto:"+dto);
		if (idControl == null || idControl <= 0)
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","id");

		if (null == dto)
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","dto");

		ControlesDTO c =  controlesDAO.getControlesById(idControl);

		if (c == null)
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"controles.not.exist", idControl);	

		Utils.validarDTO(dto);

		try{

			if(dto.getEliminar()!=null){
				if (dto.getEliminar().getTextos()!= null){
					for(ControlestextoDTO ct : dto.getEliminar().getTextos()){
						controlesTextoDAO.deleteControlestexto(ct);
					}
				}
			}
			if(dto.getModificar()!=null){
				if (dto.getModificar().getTextos() != null){
					for(ControlestextoDTO ct : dto.getModificar().getTextos()){
						ct.setIdcontrol(dto.getId());
						ct.setIdescribano(dto.getIdescribano());
						controlesTextoDAO.updateControlestexto(ct);
					}
				}								
			}
			if(dto.getAgregar()!=null){
				if (dto.getAgregar().getTextos() != null){
					for(ControlestextoDTO ct : dto.getAgregar().getTextos()){
						ct.setIdcontrol(dto.getId());
						ct.setIdescribano(dto.getIdescribano());
						log.info("control Texto a Crear:"+ct);
						controlesTextoDAO.createControlestexto(ct);
					}
				}
				
			}
//			log.info("dto.getIdescribano():      ............."+dto.getIdescribano());
			c.setFechamodificacion(new Date(System.currentTimeMillis()));
			c.setIdusuariomodificacion(ic.getIdUserPrincipal());
			c.setIdestado(dto.getIdestado());
			controlesDAO.updateControles(c);
		}
		catch (DataIntegrityViolationException e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.DATA_INTEGRITY_VIOLATION, "controles.constraint.violation");
		}
		dto= this.getControles(dto.getId(), ic);
		Utils.validarControl(dto);
		return dto;
	}

	
}